<?php
/*
 * Sequence Synonyms
 *
 * Copyright (c) 2009 Victor de la Torre (vdelatorre@cnio.es)
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 * 
 * http://code.google.com/p/ssynonyms/
 *
 */
 
 class Ssynonyms extends Rest {
 
 	public $inEntity = '';
 	public $inSequence = '';
 	public $stype = '';
 	public $program	= '';
 	public $database = '';
 	 public $output = '';
 	
 	/**
 	 * __construct function.
 	 * 
 	 * @access private
 	 * @param mixed $entity
 	 * @param mixed $sequence
 	 * @return void
 	 */
 	function __construct($entity,$sequence,$program,$database){
 		
 		$this->inEntity 	= $entity;
 		
 		$this->inSequence	= $sequence;
 		$this->program		= $program;
 		$this->setStype();
 		$this->setDatabase($database);
 	}
 	
 	/**
 	 * setInType function.
 	 * 
 	 * @access public
 	 * @return void
 	 */
 	function setStype(){
 		
 		if (preg_match('/[m|M|p|P|v|V]/',$this->inSequence)){
 			$this->stype = 'protein';
 		}else if (preg_match('/[a|A|g|G|c|C]/',$this->inSequence) and preg_match('/|t|T/',$this->inSequence))	
 			$this->stype = 'dna';
		else if (preg_match('/[a|A|g|G|c|C]/',$this->inSequence) and preg_match('/|u|U/',$this->inSequence))	
 			$this->stype = 'dna';
 	}
 	
 	function setDatabase($database){
 		
 		if ($database)
 			$this->database = $database;
 		else if ($this->stype == 'protein')
 			$this->database = 'uniprotkb';
 		else if ($this->stype == 'dna'){
 			if ($this->program == 'blastx')
 				$this->database = 'uniprotkb';
 			else	
 				$this->database = 'emall';	
 		}		
 	}
 	
 	/**
 	 * callBlast function.
 	 * 
 	 * @access public
 	 * @return void
 	 */
 	function callBlast(){
 	
  		$url = 'http://bwsp.bioinfo.cnio.es/bwsp.php?bwsp_service=ebiNcbiblast&bwsp_response_format=raw&bwsp_url=http://www.ebi.ac.uk/Tools/services/rest/ncbiblast/?email=vdelatorre@cnio.es,alignments=5,stype='.$this->stype.',program='.$this->program.',database='.$this->database.',sequence='.$this->inSequence;
 		//echo $url;
 		$tmp = $this->getProxyResponse($url);
 		$results = explode("<?xml version='1.0' encoding='ISO-8859-1'?>",$tmp);
 		//echo $results[1];
 		return $results[1];
 	}
 	
 	/**
 	 * parseBlastResults function.
 	 * 
 	 * @access public
 	 * @param mixed $results
 	 * @return void
 	 */
 	function parseBlastResults($results){
 	
 		$minScore = 100;
 		
		if (!$results)
		  	return false;	

		$entities = array();
		$i = 0;
		if ($results->SequenceSimilaritySearchResult->hits['total'] == 0){
			$this->output = '<info>No results found</info>';
			
		}else{
		  	foreach($results->SequenceSimilaritySearchResult->hits->hit as $hit){
	            if ($i >= 5)
	            	break;
	            	
	            	
				$entity['id'] 			= $hit['id'];
				$entity['ac'] 			= $hit['ac'];
				$entity['length'] 		= $hit['length'];
		  		$entity['description']	= $hit['description']; 
		   		$bestAlign 				= $hit->alignments->alignment;
		  		$entity['score'] 		= $bestAlign->score;
		  		$entity['bits'] 		= $bestAlign->bits;
		  		$entity['expectation']	= $bestAlign->expectation;
		  		$entity['identity']		= $bestAlign->identity;
		  		
		  		//if ($entity['score'] >$minScore and (preg_match('/e/',$entity['expectation']) or $entity['expectation'] <= 0)){
		  			array_push($entities,$entity);
		  			$i++;
		  		//}	
		  	}
	  	}
	  	//echo implode(',',$entities);
	  	return $entities;	

 	}
 	
 	
 	/**
 	 * callEFetchSeq function.
 	 * 
 	 * @access public
 	 * @param mixed $id
 	 * @return void
 	 */
 	function callEFetchSeq($id){
 		
 		$url = 'http://bwsp.bioinfo.cnio.es/bwsp.php?bwsp_service=efetchSeq&bwsp_response_format=raw&bwsp_url=http://www.ncbi.nlm.nih.gov/entrez/eutils/soap/v2.0/efetch_seq.wsdl,id='.$id;
 		$tmp = $this->getProxyResponse($url);
 		$results = explode('<?xml version="1.0" encoding="utf-8"?>',$tmp);
 		return str_replace(array('<object_stdClass>','</object_stdClass>'),'',$results[1]);
 	}
 	
 	
    /**
     * parseEFetchSeqResults function.
     * 
     * @access public
     * @param mixed $xml
     * @return void
     */
    function parseEFetchSeqResults($xml){
 		if (!$xml)
		  	return false;
		 
	
		$syn[base64_encode('locus')] 		= $xml->GBSeq->GBSeq_locus;
		$syn[base64_encode('length')] 		= $xml->GBSeq->GBSeq_length;
		$syn[base64_encode('definition')] 	= $xml->GBSeq->GBSeq_definition;
		$syn[base64_encode('organism')] 	= $xml->GBSeq->GBSeq_organism;
				
		$features =  $xml->xpath('GBSeq/GBSeq_feature-table/GBFeature');
		$ofeatures = array();
		if ($features){
			while(list( , $node) = each($features)) {
				
				for($i=0;$i<=20;$i++){
					$of = array();
					$f = "_".$i;
					if ($node->$f){
						$feature = $node->$f;
						for($j=0;$j<=10;$j++){
							$c = "_".$j;
							$qname 	= $feature->GBFeature_quals->GBQualifier->$c->GBQualifier_name;
							$qvalue = $feature->GBFeature_quals->GBQualifier->$c->GBQualifier_value;
							if ($qname && $qvalue){
								$of[base64_encode($qname)] = $qvalue;
								//echo $qname.': '.$qvalue.'<br>';
							}	
						}
						if (count($of))
							array_push($ofeatures,$of);
					}else
						break;	
				}
	
			}
			$syn[base64_encode('features')] = $ofeatures;
		}
		return $syn;	
 	}
 	
 	/**
 	 * formatBlast function.
 	 * 
 	 * @access public
 	 * @param mixed $entities
 	 * @return void
 	 */
 	function formatBlast($entities){
 	
 		$this->output = "<?xml version='1.0' encoding='UTF-8'?>\n";
 		$this->output .= "<synonyms>\n";
 		foreach($entities as $e){
 			$this->output .= "<synonym>\n";
 			$this->output .= "<blast>\n";
 			$this->output .= "<id>".$e['id']."</id>\n";
 			$this->output .= "<ac>".$e['ac']."</ac>\n";
 			$this->output .= "<length>".$e['length']."</length>\n";
 			$this->output .= "<expectation>".$e['expectation']."</expectation>\n";
 			$this->output .= "<score>".$e['score']."</score>\n";
 			$this->output .= "<bits>".$e['bits']."</bits>\n";
 			$this->output .= "<description>".$e['description']."</description>\n";
 			$this->output .= "<identity>".$e['identity']."</identity>\n";
 			$this->output .= "</blast>\n";
 			$this->output .= "<ncbi>\n";

 			$asn 		= simplexml_load_string($this->callEFetchSeq($e['id']));
	
 			$features	= $this->parseEFetchSeqResults($asn);
			if ($features)
 				$this->formatFeatures($features);
 			
 			$this->output .= "</ncbi>\n";
 			$this->output .= "</synonym>\n";
 			
 		}
 		$this->output .= "</synonyms>\n";
 	}
 	
 	
 	/**
 	 * formatFeatures function.
 	 * 
 	 * @access public
 	 * @param mixed $features
 	 * @return void
 	 */
 	function formatFeatures($features){
 	
 		foreach ($features as $k=>$v){
 			//echo $k." | ".base64_decode($k)." | ".$v.'<br>';
 			$nl = false;
 			if (!base64_decode($k) || in_array($k,array(10,11,12,13,14,15,16,17,18,19,20))){
 				$k = base64_encode('feature');
 				$nl = true;
 			}	
 		    $this->output .= "<".base64_decode($k).">";
 		    if ($nl)
 		    	$this->output .= "\n";
 			
 			if (!is_array($v))
 				$this->output .= $v;
 			else{
				$this->formatFeatures($v);
			}
			$this->output .= "</".base64_decode($k).">\n";		
 		}
 	}
 	
 	/**
 	 * deploy function.
 	 * 
 	 * @access public
 	 * @return void
 	 */
 	function deploy(){
 		//header ("content-type: text/xml");
 		echo $this->output;
 	}
 }
 ?>